package run.microservice.stock.response;

import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;

import java.io.Serializable;

/**
 * 统一格式返回结果
 * @author lunfangyu
 */
@Data
public class Result<T> implements Serializable {
    private static final long serialVersionUID = 8925927757015090232L;

    /** 响应编码 */
    private String code;
    /** 响应消息 */
    private String msg;
    /** 响应数据 */
    private T data;

    /** 响应消息参数，不返回给前端 */
    @JsonIgnore
    private String[] msgArgs;

    private Result(){}

    public static <T> Result<T> success() {
        Result<T> result = getInstance(ResultEnum.SUCCESS);
        return result;
    }

    public static <T> Result<T> success(T data) {
        Result<T> result = success();
        result.setData(data);
        return result;
    }

    public static <T> Result<T> error(ResultEnum resultEnum) {
        Result<T> result = getInstance(resultEnum);
        return result;
    }

    public static <T> Result<T> error(ResultEnum resultEnum, T data) {
        Result<T> result = error(resultEnum);
        result.setData(data);
        return result;
    }

    public static <T> Result<T> error(ResultEnum resultEnum, String[] msgArgs) {
        Result<T> result = error(resultEnum);
        result.setMsgArgs(msgArgs);
        return result;
    }

    public static <T> Result<T> error(ResultEnum resultEnum, String[] msgArgs, T data) {
        Result<T> result = error(resultEnum, msgArgs);
        result.setData(data);
        return result;
    }

    public boolean isSuccess() {
        return ResultEnum.SUCCESS.getCode().equals(this.code);
    }

    public void setMsg(String msg){
        this.msg = this.getLocaleMsg(msg);
    }

    public void setMsgArgs(String[] msgArgs){
        this.msgArgs = msgArgs;
        this.msg = this.formatLocaleMsg(this.msg);
    }

    private static <T> Result<T> getInstance(ResultEnum resultEnum) {
        Result<T> result = new Result<>();
        result.setCode(resultEnum.getCode());
        result.setMsg(resultEnum.getMsg());
        return result;
    }

    /**
     * 扩展点
     * 获取本地化(多语言)提示信息。
     * 如果没有多语言配置，默认返回中文提示信息
     * @return
     */
    private String getLocaleMsg(String msg) {
        /*
        * 多语言提示信息在此实现
        * 获取本地化提示信息
        * 1. 使用SpringContextUtil工具类获取消息服务类
        *    如果服务类为空，直接返回formatLocaleMsg(msg)
        * 2. 根据消息编码code和语种code获取返回信息, 语种code可以从用户登录信息获取
        *    如果信息为空，再根据消息编码code和中文语种code查询返回信息;
        *    如有查询结果，则返回formatLocaleMsg(查询结果)
        * */
        //LocaleMessageService msgService = SpringContextUtil.getBean(LocaleMessageService.class);

        return formatLocaleMsg(msg);
    }

    private String formatLocaleMsg(String msg) {
        if (msgArgs != null && msgArgs.length > 0) {
            return this.format(msg, msgArgs);
        }
        return msg;
    }

    /**
     * 同 log 格式的 format 规则
     * <p>
     * use: format("my name is {}, and i like {}!", "Tomcat", "Java")
     * </p>
     * @param message   需要转换的字符串
     * @param args 需要替换的变量
     * @return 转换后的字符串
     */
    private String format(String message, String[] args) {
        // message 为 null 返回空字符串
        if (message == null) {
            return "";
        }
        // 参数为 null 或者为空
        if (args == null || args.length == 0) {
            return message;
        }
        StringBuilder sb = new StringBuilder((int) (message.length() * 1.5));
        int cursor = 0;
        int index = 0;
        int argsLength = args.length;
        for (int start, end; (start = message.indexOf('{', cursor)) != -1 && (end = message.indexOf('}', start)) != -1 && index < argsLength; ) {
            sb.append(message, cursor, start);
            sb.append(args[index]);
            cursor = end + 1;
            index++;
        }
        sb.append(message.substring(cursor));
        return sb.toString();
    }

}
